<template>
	<div class="toolbar-container">
		<div class="left-toolbar">
			<Button type="text" :disabled="undoDisabled" :title="i18nt('designer.toolbar.undoHint')"
				@click="undoHistory" style="background-color: transparent;">
				<svg-icon icon-class="undo" />
			</Button>
			<Button type="text" :disabled="redoDisabled" :title="i18nt('designer.toolbar.redoHint')"
				@click="redoHistory" style="background-color: transparent;">
				<svg-icon icon-class="redo" />
			</Button>
			<ButtonGroup style="margin-left: 20px">
				<Button :type="layoutType === 'PC' ? 'primary': 'default'" @click="changeLayoutType('PC')">
					{{i18nt('designer.toolbar.pcLayout')}}
				</Button>
				<Button :type="layoutType === 'H5' ? 'primary': 'default'" @click="changeLayoutType('H5')">
					{{i18nt('designer.toolbar.mobileLayout')}}
				</Button>
			</ButtonGroup>
		</div>

		<div class="right-toolbar">
			<Button type="text" @click="clearFormWidget"><i class="ivu-icon ivu-icon-ios-trash" />{{i18nt('designer.toolbar.clear')}}</Button>
			<Button type="text" @click="previewForm"><i class="ivu-icon ivu-icon-ios-eye-outline" />{{i18nt('designer.toolbar.preview')}}</Button>
			<Button type="text" @click="importJson">{{i18nt('designer.toolbar.importJson')}}</Button>
			<Button type="text" @click="exportJson">{{i18nt('designer.toolbar.exportJson')}}</Button>
			<Button type="text" @click="exportCode">{{i18nt('designer.toolbar.exportCode')}}</Button>
			<Button type="text" v-if="false">{{i18nt('designer.toolbar.generateCode')}}</Button>
			<Button type="text" @click="generateSFC"><svg-icon icon-class="vue-sfc" />{{i18nt('designer.toolbar.generateSFC')}}</Button>
		</div>

		<Modal :title="i18nt('designer.toolbar.preview')"
			v-model="showPreviewDialogFlag" :closable="true" class="small-padding-dialog" draggable
			:mask-closable="false" width="75%"
			:fullscreen ="layoutType === 'H5'">
			<div v-if="showPreviewDialogFlag">
				<div class="form-render-wrapper" :class="[layoutType === 'H5' ? 'h5-layout' : '']">
					<VFormRender ref="preForm" :form-json="formJson" :form-data="testFormData"
						@appendButtonClick="testOnAppendButtonClick" @buttonClick="testOnButtonClick"
						@formChange="handleFormChange" @change="handlerNativeChange"
						></VFormRender>
				</div>
			</div>
			<code-editor v-model="testFunc" style="display: none"></code-editor>
			<div slot="footer" class="dialog-footer">
				<Button type="primary" size="default" @click="getFormData">{{i18nt('designer.hint.getFormData')}}</Button>
				<Button type="primary" size="default" @click="resetForm">{{i18nt('designer.hint.resetForm')}}</Button>
				<Button type="primary" size="default" @click="setFormDisabled">{{i18nt('designer.hint.disableForm')}}</Button>
				<Button type="primary" size="default" @click="setFormEnabled">{{i18nt('designer.hint.enableForm')}}</Button>
				<Button type="default" size="default" @click="showPreviewDialogFlag = false">{{i18nt('designer.hint.closePreview')}}</Button>
			</div>
		</Modal>

		<Modal :title="i18nt('designer.toolbar.importJson')"
			v-model="showImportJsonDialogFlag" :closable="true" class="small-padding-dialog" draggable
			:mask-closable="false">
			<Alert show-icon>{{i18nt('designer.hint.importJsonHint')}}</Alert>
			<code-editor v-if="showImportJsonDialogFlag" :mode="'json'" :readonly="false" v-model="importTemplate"></code-editor>
			<div slot="footer" class="dialog-footer">
				<Button size="default" @click="showImportJsonDialogFlag = false">
					{{i18nt('designer.hint.cancel')}}
				</Button>
				<Button size="default" type="primary" @click="doJsonImport">
					{{i18nt('designer.hint.import')}}
				</Button>
			</div>
		</Modal>
		
		<Modal :title="i18nt('designer.toolbar.exportJson')"
			v-model="showExportJsonDialogFlag" :closable="true" class="small-padding-dialog" draggable
			:mask-closable="false">
			<code-editor v-if="showExportJsonDialogFlag" :mode="'json'" :readonly="true" v-model="jsonContent"></code-editor>
			<div slot="footer" class="dialog-footer">
				<Button size="default" type="primary" class="copy-json-btn" :data-clipboard-text="jsonRawContent">
					{{i18nt('designer.hint.copyJson')}}
				</Button>
				<Button size="default" type="default" @click="showExportJsonDialogFlag = false">
					{{i18nt('designer.hint.closePreview')}}
				</Button>
			</div>
		</Modal>

		<Modal :title="i18nt('designer.toolbar.exportCode')"
			v-model="showExportCodeDialogFlag" :closable="true" class="small-padding-dialog" draggable
			:mask-closable="false"
			width="65%">
			<Tabs type="line" class="no-box-shadow" v-model="activeCodeTab">
				<TabPane label="Vue" name="vue">
					<code-editor v-if="showExportCodeDialogFlag" :mode="'html'" :readonly="true" v-model="vueCode" :user-worker="false"></code-editor>
				</TabPane>
				<TabPane label="HTML" name="html">
					<code-editor v-if="showExportCodeDialogFlag" :mode="'html'" :readonly="true" v-model="htmlCode" :user-worker="false"></code-editor>
				</TabPane>
			</Tabs>
			<div slot="footer" class="dialog-footer">
				<Button size="default" type="primary" class="copy-vue-btn" :data-clipboard-text="vueCode">
					{{i18nt('designer.hint.copyVueCode')}}
				</Button>
				<Button size="default" type="primary" class="copy-html-btn" :data-clipboard-text="htmlCode">
					{{i18nt('designer.hint.copyHtmlCode')}}
				</Button>
				<Button size="default" type="primary" @click="saveVueCode">{{i18nt('designer.hint.saveVueCode')}}</Button>
				<Button size="default" type="primary" @click="saveHtmlCode">{{i18nt('designer.hint.saveHtmlCode')}}</Button>
				<Button size="default" type="default" @click="showExportCodeDialogFlag = false">
					{{i18nt('designer.hint.closePreview')}}
				</Button>
			</div>
		</Modal>

		<Modal :title="i18nt('designer.hint.exportFormData')"
			v-model="showFormDataDialogFlag" :closable="true" class="dialog-title-light-bg" draggable
			:mask-closable="false">
			<div style="border: 1px solid #DCDFE6">
				<code-editor v-if="showFormDataDialogFlag" :mode="'json'" :readonly="true" v-model="formDataJson"></code-editor>
			</div>
			<div slot="footer" class="dialog-footer">
				<Button size="default" type="primary" class="copy-form-data-json-btn" :data-clipboard-text="formDataRawJson">
					{{i18nt('designer.hint.copyFormData')}}
				</Button>
				<Button size="default" type="default" @click="showFormDataDialogFlag = false">
					{{i18nt('designer.hint.closePreview')}}
				</Button>
			</div>
		</Modal>
		
		
		<Modal :title="i18nt('designer.toolbar.generateSFC')" width="85%"
		           v-model="showExportSFCDialogFlag" :closable="true" class="dialog-title-light-bg" draggable
			:mask-closable="false">
		  <Tabs type="line" class="no-box-shadow no-padding" v-model="activeSFCTab">
		    <TabPane label="Vue2" name="vue2">
		      <code-editor v-if="showExportSFCDialogFlag" :mode="'html'" :readonly="true" v-model="sfcCode" :user-worker="false"></code-editor>
		    </TabPane>
		    <TabPane label="Vue3" name="vue3">
		      <code-editor v-if="showExportSFCDialogFlag" :mode="'html'" :readonly="true" v-model="sfcCodeV3" :user-worker="false"></code-editor>
		    </TabPane>
		  </Tabs>
		  <div slot="footer" class="dialog-footer">
		    <Button size="default" type="primary" class="copy-vue2-sfc-btn" :data-clipboard-text="sfcCode" @click="copyV2SFC">
		      {{i18nt('designer.hint.copyVue2SFC')}}</Button>
		    <Button size="default" type="primary" class="copy-vue3-sfc-btn" :data-clipboard-text="sfcCodeV3" @click="copyV3SFC">
		      {{i18nt('designer.hint.copyVue3SFC')}}</Button>
		    <Button size="default" @click="saveV2SFC">{{i18nt('designer.hint.saveVue2SFC')}}</Button>
		    <Button size="default" @click="saveV3SFC">{{i18nt('designer.hint.saveVue3SFC')}}</Button>
		    <Button size="default" type="default" @click="showExportSFCDialogFlag = false">
		      {{i18nt('designer.hint.closePreview')}}</Button>
		  </div>
		</Modal>
		
		
		
		<Modal :title="this.i18nt('designer.hint.saveFileTitle')" width="300px"
		    v-model="showExportSFCFileNameDialogFlag" :closable="true" class="dialog-title-light-bg" draggable
			:mask-closable="false">
			<Input type="text" size="large" v-model="saveFileName" :placeholder="i18nt('designer.hint.fileNameForSave')" clearable/>
			<div slot="footer" class="dialog-footer">
				<Button size="default" type="primary" @click="saveFileExec">{{i18nt('designer.hint.confirm')}}</Button>
				<Button size="default" type="default" @click="showExportSFCFileNameDialogFlag = false">{{i18nt('designer.hint.closePreview')}}</Button>
			</div>
		</Modal>
	</div>
</template>

<script>
	import VFormRender from '@/components-iview/form-render/index'
	import CodeEditor from '@/components-iview/code-editor/index'
	import Clipboard from 'clipboard'
	import {deepClone, copyToClipboard, generateId, getQueryParam} from "@/utils/util";
	import i18n from "../../utils/i18n";
	import {generateCode} from "../../utils/code-generator";
	import {genSFC} from "../../utils/sfc-generator";
	import loadBeautifier from "@/utils/beautifierLoader";
	import { saveAs } from 'file-saver'
	

	export default {
		name: "ToolbarPanel",
		mixins: [i18n],
		components: {
			VFormRender,
			//CodeEditor: () => import('@/components/code-editor/index'),
			CodeEditor,
			Clipboard,
		},
		props: {
			designer: Object
		},
		mounted() {
			if(this.load) this.reloadCode();
		},
		data() {
			return {
				showPreviewDialogFlag: false,
				showImportJsonDialogFlag: false,
				showExportJsonDialogFlag: false,
				showExportCodeDialogFlag: false,
				showFormDataDialogFlag: false,
				showExportSFCDialogFlag: false,
				showExportSFCFileNameDialogFlag: false,


				saveFileHandler:null,
				saveFileName:'',
				
				testFunc: '',
				importTemplate: '',
				jsonContent: '',
				jsonRawContent: '',

				formDataJson: '',
				formDataRawJson: '',

				vueCode: '',
				htmlCode: '',
				
				sfcCode: '',
				sfcCodeV3: '',

				activeCodeTab: 'vue',
				activeSFCTab: 'vue2',

				testFormData: {
					// 'userName': '666888',
					// 'productItems': [
					//   {'pName': 'iPhone12', 'pNum': 10},
					//   {'pName': 'P50', 'pNum': 16},
					// ]
				}
			}
		},
		computed: {
			formJson() {
				return {
					widgetList: this.designer.widgetList,
					formConfig: this.designer.formConfig
				}
			},

			undoDisabled() {
				return !this.designer.undoEnabled()
			},

			redoDisabled() {
				return !this.designer.redoEnabled()
			},

			layoutType() {
				return this.designer.getLayoutType()
			},

		},
		methods: {
			undoHistory() {
				this.designer.undoHistoryStep()
			},

			redoHistory() {
				this.designer.redoHistoryStep()
			},

			changeLayoutType(newType) {
				this.designer.changeLayoutType(newType)
			},

			clearFormWidget() {
				this.designer.clearDesigner()
			},

			previewForm() {
				this.showPreviewDialogFlag = true
			},
			saveFileExec(){
				this.saveAsFile(this.saveFileHandler[0],this.saveFileHandler[1])
			},
			saveAsFile(fileContent, defaultFileName) {
				let value="";
				  if (!this.saveFileName) {
					value = defaultFileName
				  }else{
					  value=this.saveFileName ;
				  }

				  if (getQueryParam('vscode') == 1) {
					this.vsSaveFile(value, fileContent)
					return
				  }

				  const fileBlob = new Blob([fileContent], { type: 'text/plain;charset=utf-8' })
				  saveAs(fileBlob ,value)
			  },

			  vsSaveFile(fileName, fileContent) {
				const msgObj = {
				  cmd: 'writeFile',
				  data: {
					fileName,
					code: fileContent
				  }
				}
				window.parent.postMessage(msgObj, '*')
			  },
			  
			importJson() {
				this.importTemplate = JSON.stringify(this.designer.getImportTemplate(), null, '  ')
				this.showImportJsonDialogFlag = true
			},

			doJsonImport() {
				try {
					let importObj = JSON.parse(this.importTemplate)
					this.designer.loadFormJson(importObj)

					this.showImportJsonDialogFlag = false
					this.$Message.success(this.i18nt('designer.hint.importJsonSuccess'))

					this.designer.emitHistoryChange()
				} catch (ex) {
					this.$Message.error(ex + '')
				}
			},

			exportJson() {
				//alert( JSON.stringify(this.designer.widgetList) )
				//this.jsonContent = JSON.stringify(this.designer.widgetList, null, '  ')
				let widgetList = deepClone(this.designer.widgetList)
				let formConfig = deepClone(this.designer.formConfig)
				this.jsonContent = JSON.stringify({
					widgetList,
					formConfig
				}, null, '  ')
				this.jsonRawContent = JSON.stringify({
					widgetList,
					formConfig
				})
				this.showExportJsonDialogFlag = true;
				this.$forceUpdate();
				this.$nextTick(() => {
					let copyClipboard = new Clipboard('.copy-json-btn')
					copyClipboard.on('success', e => {
						this.$Message.success(this.i18nt('designer.hint.copyJsonSuccess'))
						copyClipboard.destroy() // 释放内存
					})
					copyClipboard.on('error', e => { // 不支持复制
						this.$Message.error(this.i18nt('designer.hint.copyJsonFail'))
						copyClipboard.destroy()
					})
				})
			},
			exportCode() {
				this.vueCode = generateCode(this.formJson)
				this.htmlCode = generateCode(this.formJson, 'html')
				this.showExportCodeDialogFlag = true

				this.$nextTick(() => {
					let vueClipboard = new Clipboard('.copy-vue-btn')
					vueClipboard.on('success', e => {
						this.$Message.success(this.i18nt('designer.hint.copyVueCodeSuccess'))
						vueClipboard.destroy() // 释放内存
					})
					vueClipboard.on('error', e => { // 不支持复制
						this.$Message.error(this.i18nt('designer.hint.copyVueCodeFail'))
						vueClipboard.destroy()
					})

					let htmlClipboard = new Clipboard('.copy-html-btn')
					htmlClipboard.on('success', e => {
						this.$Message.success(this.i18nt('designer.hint.copyHtmlCodeSuccess'))
						htmlClipboard.destroy() // 释放内存
					})
					htmlClipboard.on('error', e => { // 不支持复制
						this.$Message.error(this.i18nt('designer.hint.copyHtmlCodeFail'))
						htmlClipboard.destroy()
					})
				})
			},

			  copyVueCode(e) {
				copyToClipboard(this.vueCode, e,
					this.$Message,
					this.i18nt('designer.hint.copyVueCodeSuccess'),
					this.i18nt('designer.hint.copyVueCodeFail')
				)
			  },

			  copyHtmlCode(e) {
				copyToClipboard(this.htmlCode, e,
					this.$Message,
					this.i18nt('designer.hint.copyHtmlCodeSuccess'),
					this.i18nt('designer.hint.copyHtmlCodeFail')
				)
			  },

			  saveVueCode() {
				this.saveFileHandler=[this.vueCode, `vform${generateId()}.vue`];
				this.showExportSFCFileNameDialogFlag=true;
			  },

			  saveHtmlCode() {
				this.saveFileHandler=[this.htmlCode, `vform${generateId()}.vue`];
				this.showExportSFCFileNameDialogFlag=true;
			  },

			  generateSFC() {
				loadBeautifier(beautifier => {
				  this.sfcCode = genSFC(this.designer.formConfig, this.designer.widgetList, beautifier)
				  this.sfcCodeV3 = genSFC(this.designer.formConfig, this.designer.widgetList, beautifier, true)
				  this.showExportSFCDialogFlag = true
				})
			  },

			  copyV2SFC(e) {
				copyToClipboard(this.sfcCode, e,
					this.$Message,
					this.i18nt('designer.hint.copySFCSuccess'),
					this.i18nt('designer.hint.copySFCFail')
				)
			  },

			  copyV3SFC(e) {
				copyToClipboard(this.sfcCodeV3, e,
					this.$Message,
					this.i18nt('designer.hint.copySFCSuccess'),
					this.i18nt('designer.hint.copySFCFail')
				)
			  },

			  saveV2SFC() {
				this.saveFileHandler=[this.sfcCode, `vformV2-${generateId()}.vue`];
				this.showExportSFCFileNameDialogFlag=true;
				// this.saveAsFile(this.sfcCode, `vformV2-${generateId()}.vue`)
			  },

			  saveV3SFC() {
				  this.saveFileHandler=[this.sfcCodeV3, `vformV3-${generateId()}.vue`];
				  this.showExportSFCFileNameDialogFlag=true;
				// this.saveAsFile(this.sfcCodeV3, `vformV3-${generateId()}.vue`)
			  },

			getFormData() {
				this.$refs['preForm'].getFormData().then(formData => {
					//alert( JSON.stringify(formData) )

					this.formDataJson = JSON.stringify(formData, null, '  ')
					this.formDataRawJson = JSON.stringify(formData)

					this.showFormDataDialogFlag = true
					this.$nextTick(() => {
						let copyClipboard = new Clipboard('.copy-form-data-json-btn')
						copyClipboard.on('success', e => {
							this.$Message.success(this.i18nt('designer.hint.copyJsonSuccess'))
							copyClipboard.destroy() // 释放内存
						})
						copyClipboard.on('error', e => { // 不支持复制
							this.$Message.error(this.i18nt('designer.hint.copyJsonFail'))
							copyClipboard.destroy()
						})
					})
				}).catch(error => {
					this.$Message.error(error)
				})
			},

			resetForm() {
				this.$refs['preForm'].resetForm()
			},

			setFormDisabled() {
				this.$refs['preForm'].disableForm()
			},

			setFormEnabled() {
				this.$refs['preForm'].enableForm()
			},

			handleFormChange(fieldName, newValue, oldValue, formModel) {
				console.log('---formChange start---')
				console.log('fieldName', fieldName)
				console.log('newValue', newValue)
				console.log('oldValue', oldValue)
				console.log('formModel', formModel)
				console.log('---formChange end---')
			},

			testOnAppendButtonClick(clickedWidget) {
				console.log('test', clickedWidget)
			},

			testOnButtonClick(button) {
				console.log('test', button)
			},
			handlerNativeChange(args){
				
			}
		}
	}
</script>

<style lang="scss" scoped>
	div.toolbar-container {
		//border-bottom: 1px solid #EBEEF5;
	}

	.left-toolbar {
		float: left;
		font-size: 16px;
	}

	.right-toolbar {
		float: right;

		::v-deep .el-button--text {
			font-size: 14px !important;
		}
		.ivu-icon{
			font-size:18px;
		}
	}

	.el-button i {
		margin-right: 3px;
	}

	.small-padding-dialog {
		::v-deep .el-dialog__header {
			padding-top: 3px;
			padding-bottom: 3px;
			background: #f1f2f3;
		}

		::v-deep .el-dialog__body {
			padding: 12px 15px 12px 15px;

			.el-alert {
				padding: 0 10px;
			}
		}

		::v-deep .ace-container {
			border: 1px solid #DCDFE6;
		}
	}

	.dialog-title-light-bg {
		::v-deep .el-dialog__header {
			background: #f1f2f3;
		}
	}

	.no-box-shadow {
		box-shadow: none;
	}

	.form-render-wrapper {
		//height: calc(100vh - 142px);
	}

	.form-render-wrapper.h5-layout {
		margin: 0 auto;
		width: 420px;
		border-radius: 15px;
		//border-width: 10px;
		background-color:blue;
		box-shadow: 0 0 1px 10px #495060;
		height: calc(100vh - 142px);
	}
</style>
